package cool.houge.pig.infra.service.token;

import cool.houge.pig.AuthGrantType;
import cool.houge.pig.model.AuthClient;
import cool.houge.pig.repository.user.UserRepository;
import cool.houge.pig.service.auth.AuthTokenException;
import cool.houge.pig.service.auth.AuthTokenInput;
import cool.houge.pig.service.auth.TokenPreprocess;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

/**
 * 密码令牌生成.
 *
 * @author KK (kzou227@qq.com)
 */
@Component
public class PasswordTokenPreprocess implements TokenPreprocess {

  private final UserRepository userRepository;
  private final PasswordEncoder passwordEncoder;

  /**
   * @param userRepository
   * @param passwordEncoder
   */
  public PasswordTokenPreprocess(UserRepository userRepository, PasswordEncoder passwordEncoder) {
    this.userRepository = userRepository;
    this.passwordEncoder = passwordEncoder;
  }

  @Override
  public String grantType() {
    return AuthGrantType.PASSWORD.getGrantType();
  }

  @Override
  public Mono<ProcessPart> process(AuthClient authClient, AuthTokenInput input) {
    return userRepository
        .findByUsername(input.getUsername())
        .doOnNext(
            user -> {
              if (!passwordEncoder.matches(input.getPassword(), user.getPassword())) {
                throw new AuthTokenException(
                    AuthTokenException.Error.AUTHENTICATION_FAILED, "用户密码不匹配");
              }
            })
        .map(user -> ProcessPart.builder().user(user).build());
  }
}
